package com.strongmangames.DPM;

/**
 * ...Class representing one diff operation.
 * @author Rohan Feldmesser
 */

 /**-
   * The data structure representing a diff is a List of Diff objects:
   * {Diff(Operation.DELETE, "Hello"), Diff(Operation.INSERT, "Goodbye"),
   *  Diff(Operation.EQUAL, " world.")}
   * which means: delete "Hello", add "Goodbye" and keep " world."
   */
  public enum Operation {
    DELETE;
	INSERT;
	EQUAL;
  }

class Diff 
{
	// One of: INSERT, DELETE or EQUAL.
	public var operation:Operation;
    
	// The text associated with this diff operation.
    public var text:String;
    

    /**
     * Constructor.  Initializes the diff with the provided values.
     * @param operation One of INSERT, DELETE or EQUAL.
     * @param text The text being applied.
     */
    public function new(operation:Operation, text:String)
	{
		this.operation = operation;
		this.text = text;
    }

    /**
     * Display a human-readable version of this Diff.
     * @return text version.
     */
    public function ToString():String
	{
		var prettyText:String = this.text.split('\n').join('\u00b6');
		return "Diff(" + this.operation + ",\"" + prettyText + "\")";
    }

    /**
     * Is this Diff equivalent to another Diff?
     * @param d Another Diff to compare against.
     * @return true or false.
     */
    public function Equals(Dynamic obj):Bool {
		// If parameter is null return false.
		if (obj == null) {
			return false;
		}

		// If parameter cannot be cast to Diff return false.
		var p:Diff = null;
		try{p = obj;}catch (err:String) { return false; }

		// Return true if the fields match.
		return p.operation == this.operation && p.text == this.text;
    }

    public function Equals(Diff obj):Dynamic
	{
		// If parameter is null return false.
		if (obj == null) {
			return false;
		}

		// Return true if the fields match.
		return obj.operation == this.operation && obj.text == this.text;
    }

    public function GetHashCode():Int
	{
		return HashCode.getHash(text) ^ HashCode.getHash(operation);
    }
}